using System;
using System.Collections;
using System.Runtime.Serialization;
using EnvDTE;
using Microsoft.VisualStudio.Modeling.Shell;
using VSSDKAssist.Assets.Helpers;
using VSSDKAssist.Assets.References.Base;

namespace VSSDKAssist.Recipes.Common.References
{
	/// <summary>
	/// UnboundReference for a DSL VSModeling Package Class
	/// </summary>
	[Serializable]
	public class VSModelingPackageClassReference : RecipeReferenceBase
	{
		#region Constructors
		/// <summary>
		/// Initializes a new instance of the <see cref="VSModelingPackageClassReference"/> class.
		/// </summary>
		/// <param name="recipe">The recipe.</param>
		public VSModelingPackageClassReference(String recipe) : base(recipe) { } 
		#endregion

		#region Public Implementation
		/// <summary>
		/// Determines whether the reference is enabled for a particular target item,
		/// based on the condition contained in the reference.
		/// </summary>
		/// <param name="target">The <see cref="T:System.Object"/> to check for references.</param>
		/// <returns>
		/// 	<see langword="true"/> if the reference is enabled for the given <paramref name="target"/>.
		/// Otherwise, <see langword="false"/>.
		/// </returns>
		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
		public override bool IsEnabledFor(object target)
		{
			try
			{
				bool founded = false;

				ProjectItem projectItem = target as ProjectItem;

				if(projectItem == null)
				{
					return false;
				}

				Project project = projectItem.ContainingProject;

				TypeDiscoveryHelper typeDiscoveryHelper = new TypeDiscoveryHelper(this.Site as IServiceProvider);
				ICollection types = typeDiscoveryHelper.GetTypes(typeof(ModelingPackage));

				foreach(Type type in types)
				{
					if(type.Assembly.ManifestModule.Name.Equals(
						project.Properties.Item("OutputFileName").Value.ToString(), StringComparison.OrdinalIgnoreCase))
					{
						CodeClass packageClass =
							FileCodeModelHelper.FindCodeElementByTypeName(
							project, type.FullName, vsCMElement.vsCMElementClass) as CodeClass;

						founded = (packageClass.ProjectItem == projectItem);

						if(founded)
						{
							break;
						}
					}
				}

				return founded;
			}
			catch
			{
				return false;
			}
		}

		/// <summary>
		/// See <see cref="P:Microsoft.Practices.RecipeFramework.IAssetReference.AppliesTo"/>.
		/// </summary>
		/// <value></value>
		public override String AppliesTo
		{
			get { return Properties.Resources.VSModelingPackageClassReference; }
		} 
		#endregion

		#region ISerializable Members

		/// <summary>
		/// Required constructor for deserialization.
		/// </summary>
		protected VSModelingPackageClassReference(SerializationInfo info, StreamingContext context)
			: base(info, context)
		{
		}

		#endregion ISerializable Members
	}
}
